﻿using AutoMapper;
using BackData;
using Domain;
using Infratructure;
using MediatR;
using RBAC.API.Command.Role;
using System.Transactions;
using Yitter.IdGenerator;

namespace RBAC.API.Handler.Role
{
    public class RoleUpdateHandler : IRequestHandler<RoleUpdateCommand, ApiResult<int>>
    {
        private readonly IRepository<RoleModel> roleway;
        private readonly IRepository<RolePermissionModel> rolepermissionway;
        private readonly IRepository<PermissionModel> permissionway;
        private readonly IMapper mapper;
        private readonly ILogger<RoleGetHandler> log;
        private readonly IHttpContextAccessor httpContextAccessor;

        public RoleUpdateHandler(IRepository<RoleModel> roleway, IRepository<RolePermissionModel> rolepermissionway,
            IRepository<PermissionModel> permissionway, IMapper mapper, ILogger<RoleGetHandler> log, IHttpContextAccessor httpContextAccessor)
        {
            this.roleway = roleway;
            this.rolepermissionway = rolepermissionway;
            this.permissionway = permissionway;
            this.mapper = mapper;
            this.log = log;
            this.httpContextAccessor = httpContextAccessor;
        }
        /// <summary>
        /// 修改角色信息
        /// </summary>
        /// <param name="request">参数</param>
        /// <param name="cancellationToken">取消</param>
        /// <returns>影响行数</returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult<int>> Handle(RoleUpdateCommand request, CancellationToken cancellationToken)
        {
            ApiResult<int> res = new ApiResult<int>();
            var i = 0;
            var j = 0;
            var c = await Del(request.Id);
            var role = mapper.Map<RoleModel>(request);
            var permissionIds = request.PermissionIdArray.Split(',')
                                  .Select(s => long.Parse(s.Trim()))
                                  .ToArray();
            using (TransactionScope tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    i = await roleway.Updateway(role);

                    foreach (long item in permissionIds)  //再更新
                    {
                        RolePermissionModel userrole = new RolePermissionModel()
                        {
                            Id = YitIdHelper.NextId(),
                            PermissionId = item,
                            RoleId = role.Id,
                            IsDel = false
                        };
                        j += await rolepermissionway.Addway(userrole);
                    }
                    tran.Complete();  //事务回滚
                    if (i > 0 && j > 0&&c>0)
                    {
                        log.LogInformation($"{httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(x => x.Type == "UserName")?.Value ?? "默认值"}角色修改成功");
                        res.Message = $"角色修改成功";
                        res.Code = StateCode.OK;
                        res.Data = i + j;
                        return res;
                    }
                    else
                    {
                        res.Message = $"角色修改失败";
                        res.Code = StateCode.Fail;
                        return res;
                    }
                }
                catch (Exception ex)
                {
                    log.LogError($"{httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(x => x.Type == "UserName")?.Value ?? "默认值"}角色修改时发生异常{ex.Message}");
                    throw;
                }
            }

        }
        /// <summary>
        /// 软删掉之前分配的权限
        /// </summary>
        /// <param name="RoleId"></param>
        /// <returns></returns>
        public async Task<int> Del(long RoleId)
        {
            int c = 0;
            using (TransactionScope tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    var userroles = rolepermissionway.GetAll().Where(x => x.RoleId == RoleId).ToList();
                    foreach (var item in userroles)  //先删除
                    {
                        item.IsDel = true;
                        c += await rolepermissionway.Updateway(item);
                    }
                    tran.Complete();
                }
                catch (Exception)
                {
                    throw;
                }
            }
            return c;
        }
    }
}
